import { prisma } from '../db/prisma';
import { createSuccessResponse, createErrorResponse } from '../utils/response';
import { z } from 'zod';
import { MarketType, TerminalType } from '@prisma/client';
import * as iconv from 'iconv-lite';

// 客户数据验证 schema
const clientDataSchema = z.object({
  clientCode: z.string().min(1).max(12),
  clientName: z.string().min(1).max(100),
  marketType: z.nativeEnum(MarketType),
  terminalType: z.nativeEnum(TerminalType),
});

// 导入数据验证 schema
const importDataSchema = z.object({
  managerId: z.number().int().positive(),
  serviceIds: z.array(z.number().int().positive()).min(1),
  clients: z.array(clientDataSchema).min(1),
});

// 获取导入选项的 schema
const getImportOptionsSchema = z.object({
  search: z.string().optional(),
});

// 文件解析的 schema
const parseFileSchema = z.object({
  fileBuffer: z.instanceof(Buffer),
  fileName: z.string(),
});

export class ImportService {
  /**
   * 使用 iconv-lite 检测文件编码
   * @param buffer 文件字节数组
   * @returns 检测到的编码
   */
  private static detectEncodingWithIconvLite(buffer: Buffer): string {
    // 检查 BOM
    if (buffer.length >= 3 &&
        buffer[0] === 0xEF &&
        buffer[1] === 0xBB &&
        buffer[2] === 0xBF) {
      return 'utf8';
    }

    if (buffer.length >= 2) {
      // UTF-16 LE BOM
      if (buffer[0] === 0xFF && buffer[1] === 0xFE) {
        return 'utf16le';
      }
      // UTF-16 BE BOM
      if (buffer[0] === 0xFE && buffer[1] === 0xFF) {
        return 'utf16be';
      }
    }

    // 尝试不同编码进行解码测试
    const encodingsToTry = ['utf8', 'gbk', 'gb2312', 'big5', 'shift_jis'];

    for (const encoding of encodingsToTry) {
      try {
        const decoded = iconv.decode(buffer, encoding);

        // 检查解码质量
        const hasReplacementChar = decoded.includes('\uFFFD');
        const hasValidContent = decoded.trim().length > 0;
        const hasChinese = /[\u4e00-\u9fa5]/.test(decoded);

        // 如果没有替换字符且有有效内容，认为编码正确
        if (!hasReplacementChar && hasValidContent) {
          console.log(`✅ 编码检测成功: ${encoding}`);
          return encoding;
        }

        // 如果包含中文且替换字符很少，也可能是正确的编码
        if (hasChinese && decoded.split('\uFFFD').length - 1 < decoded.length * 0.05) {
          console.log(`✅ 编码检测成功 (包含中文): ${encoding}`);
          return encoding;
        }
      } catch (error) {
        console.log(`❌ 编码 ${encoding} 测试失败:`, error);
        continue;
      }
    }

    // 默认返回 UTF-8
    console.log('⚠️ 编码检测失败，使用默认 UTF-8');
    return 'utf8';
  }

  /**
   * 解析 CSV 文件内容为客户数据
   * @param content 文件内容字符串
   * @returns 解析后的客户数据数组
   */
  private static parseCSVContent(content: string): { clients: any[], errors: string[] } {
    const lines = content.split('\n').map(line => line.trim()).filter(line => line.length > 0);
    const clients: any[] = [];
    const errors: string[] = [];

    if (lines.length === 0) {
      errors.push('文件内容为空');
      return { clients, errors };
    }

    // 跳过标题行（如果存在）
    const dataLines = lines[0].includes('客户代码') || lines[0].includes('clientCode') ? lines.slice(1) : lines;

    for (let i = 0; i < dataLines.length; i++) {
      const line = dataLines[i];
      const lineNumber = i + (lines[0].includes('客户代码') ? 2 : 1);

      try {
        // 解析 CSV 行（简单的逗号分割，可以根据需要改进）
        const parts = line.split(',').map(part => part.trim());

        if (parts.length < 4) {
          errors.push(`第 ${lineNumber} 行：数据列数不足，需要至少4列（客户代码,客户名称,市场类型,终端类型）`);
          continue;
        }

        const [clientCode, clientName, marketTypeStr, terminalTypeStr] = parts;

        // 验证市场类型
        const marketType = marketTypeStr === '城网' ? MarketType.城网 :
                          marketTypeStr === '农网' ? MarketType.农网 : null;
        if (!marketType) {
          errors.push(`第 ${lineNumber} 行：无效的市场类型 "${marketTypeStr}"，应为 "城网" 或 "农网"`);
          continue;
        }

        // 验证终端类型
        const terminalType = terminalTypeStr === '普通终端' ? TerminalType.普通终端 :
                            terminalTypeStr === '一般现代终端' ? TerminalType.一般现代终端 :
                            terminalTypeStr === '加盟终端' ? TerminalType.加盟终端 :
                            terminalTypeStr === '直营终端' ? TerminalType.直营终端 : null;
        if (!terminalType) {
          errors.push(`第 ${lineNumber} 行：无效的终端类型 "${terminalTypeStr}"，应为 "普通终端"、"一般现代终端"、"加盟终端" 或 "直营终端"`);
          continue;
        }

        // 验证客户数据
        try {
          const clientData = clientDataSchema.parse({
            clientCode: clientCode.trim(),
            clientName: clientName.trim(),
            marketType,
            terminalType,
          });
          clients.push(clientData);
        } catch (validationError) {
          if (validationError instanceof z.ZodError) {
            const errorMessages = validationError.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`);
            errors.push(`第 ${lineNumber} 行：数据验证失败 - ${errorMessages.join(', ')}`);
          } else {
            errors.push(`第 ${lineNumber} 行：数据验证失败`);
          }
        }
      } catch (error) {
        errors.push(`第 ${lineNumber} 行：解析失败 - ${error}`);
      }
    }

    return { clients, errors };
  }

  /**
   * 解析上传的文件
   * @param input 包含文件缓冲区和文件名的输入
   * @returns 解析结果
   */
  static async parseFile(input: z.infer<typeof parseFileSchema>) {
    try {
      const validatedInput = parseFileSchema.parse(input);
      const { fileBuffer, fileName } = validatedInput;

      console.log(`📁 开始解析文件: ${fileName}, 大小: ${fileBuffer.length} bytes`);

      // 检测文件编码
      const detectedEncoding = this.detectEncodingWithIconvLite(fileBuffer);
      console.log(`🔍 检测到的编码: ${detectedEncoding}`);

      // 使用检测到的编码解码文件
      let decodedContent: string;
      try {
        decodedContent = iconv.decode(fileBuffer, detectedEncoding);

        // 验证解码结果质量
        const replacementCharCount = (decodedContent.match(/\uFFFD/g) || []).length;
        const totalLength = decodedContent.length;
        const replacementRatio = totalLength > 0 ? replacementCharCount / totalLength : 0;

        console.log(`📊 解码统计: 总字符 ${totalLength}, 替换字符 ${replacementCharCount}, 替换率 ${(replacementRatio * 100).toFixed(2)}%`);

        if (replacementRatio > 0.1) {
          console.log(`⚠️ 替换字符率过高，尝试其他编码`);

          // 尝试其他常见编码
          const fallbackEncodings = ['utf8', 'gbk', 'gb2312', 'big5'];
          let bestResult = { text: decodedContent, encoding: detectedEncoding, ratio: replacementRatio };

          for (const fallbackEncoding of fallbackEncodings) {
            if (fallbackEncoding === detectedEncoding) continue;

            try {
              const fallbackText = iconv.decode(fileBuffer, fallbackEncoding);
              const fallbackReplacementCount = (fallbackText.match(/\uFFFD/g) || []).length;
              const fallbackReplacementRatio = fallbackText.length > 0 ? fallbackReplacementCount / fallbackText.length : 0;

              if (fallbackReplacementRatio < bestResult.ratio) {
                bestResult = {
                  text: fallbackText,
                  encoding: fallbackEncoding,
                  ratio: fallbackReplacementRatio
                };
                console.log(`✅ 找到更好的编码: ${fallbackEncoding} (替换率: ${(fallbackReplacementRatio * 100).toFixed(2)}%)`);
              }
            } catch (error) {
              console.log(`❌ 编码 ${fallbackEncoding} 解码失败:`, error);
            }
          }

          decodedContent = bestResult.text;
          console.log(`📄 最终使用编码: ${bestResult.encoding}`);
        } else {
          console.log(`✅ 解码成功，编码: ${detectedEncoding}`);
        }
      } catch (error) {
        console.error(`❌ 使用编码 ${detectedEncoding} 解码失败:`, error);

        // 最后的回退方案：尝试 UTF-8
        try {
          decodedContent = iconv.decode(fileBuffer, 'utf8');
          console.log(`🔄 UTF-8 回退解码完成`);
        } catch (fallbackError) {
          console.error(`❌ UTF-8 回退解码也失败:`, fallbackError);
          return createErrorResponse('文件解码失败，可能文件已损坏', 'FILE_DECODE_ERROR');
        }
      }

      // 解析 CSV 内容
      const { clients, errors } = this.parseCSVContent(decodedContent);

      // 统计有效行数（过滤空行，与解析逻辑保持一致）
      const validLines = decodedContent.split('\n').map(line => line.trim()).filter(line => line.length > 0);

      const result = {
        fileName,
        encoding: detectedEncoding,
        totalLines: validLines.length,
        parsedClients: clients.length,
        clients,
        errors,
        preview: decodedContent.substring(0, 500), // 前500字符预览
      };

      if (errors.length > 0) {
        return createSuccessResponse(result, `文件解析完成，但有 ${errors.length} 个错误`);
      } else {
        return createSuccessResponse(result, `文件解析成功，共解析 ${clients.length} 条客户数据`);
      }
    } catch (error) {
      console.error('文件解析失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('文件解析失败', 'FILE_PARSE_ERROR');
    }
  }
  // 获取导入选项（客户经理和服务项目列表）
  static async getImportOptions(input: z.infer<typeof getImportOptionsSchema>) {
    try {
      console.log('ImportService.getImportOptions 开始执行，输入参数:', input);
      const validatedInput = getImportOptionsSchema.parse(input);
      const { search } = validatedInput;

      // 构建查询条件
      const managerWhere: any = {};
      const serviceWhere: any = {};

      if (search) {
        managerWhere.OR = [
          { username: { contains: search } },
          { fullName: { contains: search } },
        ];
        serviceWhere.OR = [
          { serviceName: { contains: search } },
        ];
      }

      console.log('查询客户经理，条件:', managerWhere);
      // 获取客户经理列表
      const managers = await prisma.manager.findMany({
        where: managerWhere,
        select: {
          id: true,
          username: true,
          fullName: true,
          _count: {
            select: {
              clientAssignments: true,
            }
          }
        },
        orderBy: { fullName: 'asc' },
      });
      console.log('查询到的客户经理数量:', managers.length);
      console.log('客户经理数据:', managers);

      console.log('查询服务项目，条件:', serviceWhere);
      // 获取服务项目列表
      const services = await prisma.service.findMany({
        where: serviceWhere,
        select: {
          id: true,
          serviceName: true,
          completionCycle: true,
          cycleValue: true,
          startDate: true,
          endDate: true,
          _count: {
            select: {
              clientAssignments: true,
            }
          }
        },
        orderBy: { serviceName: 'asc' },
      });
      console.log('查询到的服务项目数量:', services.length);
      console.log('服务项目数据:', services);

      const result = {
        managers,
        services,
        marketTypes: Object.values(MarketType),
        terminalTypes: Object.values(TerminalType),
      };

      console.log('最终返回结果:', result);
      return createSuccessResponse(result, '获取导入选项成功');
    } catch (error) {
      console.error('获取导入选项失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.errors);
      }
      return createErrorResponse('获取导入选项失败', 'GET_IMPORT_OPTIONS_ERROR');
    }
  }
  
  // 导入客户数据
  static async importClients(input: z.infer<typeof importDataSchema>) {
    try {
      const validatedInput = importDataSchema.parse(input);
      const { managerId, serviceIds, clients } = validatedInput;
      
      // 验证客户经理是否存在
      const manager = await prisma.manager.findUnique({
        where: { id: managerId }
      });
      
      if (!manager) {
        return createErrorResponse('客户经理不存在', 'MANAGER_NOT_FOUND');
      }
      
      // 验证服务项目是否存在
      const services = await prisma.service.findMany({
        where: { id: { in: serviceIds } }
      });
      
      if (services.length !== serviceIds.length) {
        return createErrorResponse('部分服务项目不存在', 'SERVICES_NOT_FOUND');
      }
      
      // 检查客户代码是否重复
      const clientCodes = clients.map(c => c.clientCode);
      const duplicateCodes = clientCodes.filter((code, index) => clientCodes.indexOf(code) !== index);
      
      if (duplicateCodes.length > 0) {
        return createErrorResponse(`客户代码重复: ${duplicateCodes.join(', ')}`, 'DUPLICATE_CLIENT_CODES');
      }
      
      // 检查客户是否已经绑定到当前服务项目
      const existingServiceAssignments = await prisma.clientServiceAssignment.findMany({
        where: {
          serviceId: { in: serviceIds },
          client: {
            clientCode: { in: clientCodes }
          }
        },
        include: {
          client: {
            select: { clientCode: true }
          },
          service: {
            select: { serviceName: true }
          }
        }
      });

      if (existingServiceAssignments.length > 0) {
        const conflictInfo = existingServiceAssignments.map(assignment =>
          `${assignment.client.clientCode}(${assignment.service.serviceName})`
        );
        return createErrorResponse(`以下客户已绑定到相应服务项目: ${conflictInfo.join(', ')}`, 'CLIENT_SERVICE_ALREADY_ASSIGNED');
      }

      // 检查或创建客户记录
      const existingClients = await prisma.client.findMany({
        where: { clientCode: { in: clientCodes } },
        select: { id: true, clientCode: true, clientName: true, marketType: true, terminalType: true }
      });

      const existingClientCodes = existingClients.map(c => c.clientCode);
      const newClientsData = clients.filter(c => !existingClientCodes.includes(c.clientCode));

      // 使用事务处理导入，增加超时时间
      const result = await prisma.$transaction(async (tx) => {
        const importResults = {
          createdClients: 0,
          createdManagerAssignments: 0,
          createdServiceAssignments: 0,
          errors: [] as string[],
        };

        // 批量创建新客户
        const createdClients = [];
        if (newClientsData.length > 0) {
          try {
            for (const clientData of newClientsData) {
              const client = await tx.client.create({
                data: {
                  clientCode: clientData.clientCode,
                  clientName: clientData.clientName,
                  marketType: clientData.marketType,
                  terminalType: clientData.terminalType,
                }
              });
              createdClients.push(client);
              importResults.createdClients++;
            }
          } catch (error) {
            importResults.errors.push(`批量创建客户失败: ${error}`);
            return importResults;
          }
        }

        // 合并所有需要分配的客户（新创建的 + 已存在的）
        const allClientsForAssignment = [...createdClients, ...existingClients];

        // 批量创建客户经理关联（包括新客户和已存在的客户）
        if (allClientsForAssignment.length > 0) {
          try {
            const managerAssignments = allClientsForAssignment.map(client => ({
              managerId,
              clientId: client.id,
            }));

            await tx.managerClientAssignment.createMany({
              data: managerAssignments,
              skipDuplicates: true,
            });
            importResults.createdManagerAssignments = managerAssignments.length;
          } catch (error) {
            importResults.errors.push(`批量创建客户经理关联失败: ${error}`);
          }
        }

        // 批量创建服务项目关联（包括新客户和已存在的客户）
        if (allClientsForAssignment.length > 0 && serviceIds.length > 0) {
          try {
            const serviceAssignments = [];
            for (const client of allClientsForAssignment) {
              for (const serviceId of serviceIds) {
                serviceAssignments.push({
                  clientId: client.id,
                  serviceId,
                });
              }
            }

            await tx.clientServiceAssignment.createMany({
              data: serviceAssignments,
              skipDuplicates: true,
            });
            importResults.createdServiceAssignments = serviceAssignments.length;
          } catch (error) {
            importResults.errors.push(`批量创建服务项目关联失败: ${error}`);
          }
        }

        return importResults;
      }, {
        timeout: 30000, // 增加超时时间到30秒
      });
      
      const message = result.errors.length > 0 
        ? `导入完成，但有 ${result.errors.length} 个错误`
        : '客户数据导入成功';
      
      return createSuccessResponse(result, message);
    } catch (error) {
      console.error('导入客户数据失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('导入客户数据失败', 'IMPORT_CLIENTS_ERROR');
    }
  }
  
  // 预览导入数据（验证但不实际导入）
  static async previewImport(input: z.infer<typeof importDataSchema>) {
    try {
      const validatedInput = importDataSchema.parse(input);
      const { managerId, serviceIds, clients } = validatedInput;
      
      const validationResults = {
        valid: true,
        errors: [] as string[],
        warnings: [] as string[],
        summary: {
          totalClients: clients.length,
          managerInfo: null as any,
          servicesInfo: [] as any[],
        }
      };
      
      // 验证客户经理
      const manager = await prisma.manager.findUnique({
        where: { id: managerId },
        select: { id: true, username: true, fullName: true }
      });
      
      if (!manager) {
        validationResults.valid = false;
        validationResults.errors.push('客户经理不存在');
      } else {
        validationResults.summary.managerInfo = manager;
      }
      
      // 验证服务项目
      const services = await prisma.service.findMany({
        where: { id: { in: serviceIds } },
        select: { id: true, serviceName: true }
      });
      
      if (services.length !== serviceIds.length) {
        validationResults.valid = false;
        validationResults.errors.push('部分服务项目不存在');
      } else {
        validationResults.summary.servicesInfo = services;
      }
      
      // 检查客户代码重复
      const clientCodes = clients.map(c => c.clientCode);
      const duplicateCodes = clientCodes.filter((code, index) => clientCodes.indexOf(code) !== index);
      
      if (duplicateCodes.length > 0) {
        validationResults.valid = false;
        validationResults.errors.push(`客户代码重复: ${duplicateCodes.join(', ')}`);
      }
      
      // 检查客户是否已经绑定到当前服务项目
      const existingServiceAssignments = await prisma.clientServiceAssignment.findMany({
        where: {
          serviceId: { in: serviceIds },
          client: {
            clientCode: { in: clientCodes }
          }
        },
        include: {
          client: {
            select: { clientCode: true }
          },
          service: {
            select: { serviceName: true }
          }
        }
      });

      if (existingServiceAssignments.length > 0) {
        const conflictInfo = existingServiceAssignments.map(assignment =>
          `${assignment.client.clientCode}(${assignment.service.serviceName})`
        );
        validationResults.valid = false;
        validationResults.errors.push(`以下客户已绑定到相应服务项目: ${conflictInfo.join(', ')}`);
      }

      // 检查客户是否存在于系统中（用于信息提示，不阻止导入）
      const existingClients = await prisma.client.findMany({
        where: { clientCode: { in: clientCodes } },
        select: { clientCode: true }
      });

      if (existingClients.length > 0) {
        const existingCodes = existingClients.map(c => c.clientCode);
        validationResults.warnings.push(`以下客户已存在于系统中，将直接绑定到服务项目: ${existingCodes.join(', ')}`);
      }
      
      return createSuccessResponse(validationResults, '导入预览完成');
    } catch (error) {
      console.error('预览导入数据失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('预览导入数据失败', 'PREVIEW_IMPORT_ERROR');
    }
  }
}
